package com.evil.application.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.evil.application.mapper.ApplicationFormEnclosureMapper;
import com.evil.application.pojo.dto.form.enclosure.FormEnclosureDTO;
import com.evil.application.pojo.entity.ApplicationForm;
import com.evil.application.pojo.entity.ApplicationFormEnclosure;
import com.evil.application.service.ApplicationFormEnclosureService;
import com.evil.common.core.enums.BaseEnum;
import com.evil.common.core.exception.BusinessException;
import com.evil.common.core.util.StreamUtil;
import com.evil.common.core.enums.SwitchEnum;
import com.evil.common.file.dto.FileRespDTO;
import com.evil.file.api.RemoteFileService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 应用表单附件表
 *
 * @author liyang
 * @date 2022-08-08 00:00
 */
@Slf4j
@RestController
@AllArgsConstructor
public class ApplicationFormEnclosureServiceImpl extends ServiceImpl<ApplicationFormEnclosureMapper, ApplicationFormEnclosure> implements ApplicationFormEnclosureService {

    private final RemoteFileService remoteFileService;

    private final ApplicationLogServiceImpl logService;

    /**
     * 获取表单附件列表
     *
     * @param formId formId
     * @return ApplicationFormEnclosure 列表
     */
    @Override
    public List<ApplicationFormEnclosure> findByFormId(Long formId) {
        return this.baseMapper.findByFormId(formId);
    }

    /**
     * 获取表单附件基础信息列表
     *
     * @param formId formId
     * @return ApplicationFormEnclosure 列表
     */
    @Override
    public List<FormEnclosureDTO> findBaseByFormId(Long formId) {
        List<ApplicationFormEnclosure> formEnclosures = this.findByFormId(formId);

        Set<Long> fileIds = StreamUtil.transSetT(formEnclosures, ApplicationFormEnclosure::getFileId);
        Map<Long, FileRespDTO> fileMap = remoteFileService.findBaseMapByFileIds_check(fileIds);

        return formEnclosures.stream()
                .map(e -> {
                    FormEnclosureDTO formEnclosureDTO;
                    if (fileMap.containsKey(e.getFileId())) {
                        formEnclosureDTO = new FormEnclosureDTO(e);
                        BeanUtil.copyProperties(fileMap.get(e.getFileId()), formEnclosureDTO);
                    } else {
                        formEnclosureDTO = new FormEnclosureDTO(e);
                    }
                    return formEnclosureDTO;
                })
                .collect(Collectors.toList());
    }

    /**
     * 保存表单附件
     *
     * @param applicationForm applicationForm
     * @param formEnclosures  formEnclosures
     */
    @Override
    public void modifyFormEnclosure(ApplicationForm applicationForm, List<FormEnclosureDTO> formEnclosures) {
        List<Long> enclosuresIds = new ArrayList<>();
        for (FormEnclosureDTO formEnclosure : formEnclosures) {
            Long applicationFormEnclosureId = formEnclosure.getApplicationFormEnclosureId();
            if (null != applicationFormEnclosureId) {
                enclosuresIds.add(applicationFormEnclosureId);
            }
        }

        List<ApplicationFormEnclosure> formEnclosureList = this.baseMapper.findByFormId(applicationForm.getFormId());
        Map<Long, ApplicationFormEnclosure> enclosureMap = formEnclosureList.stream()
                .collect(Collectors.toMap(ApplicationFormEnclosure::getFormEnclosureId, e -> e));

        // 新增编辑
        List<ApplicationFormEnclosure> modifies = formEnclosures.stream().map(e -> {
            ApplicationFormEnclosure applicationFormEnclosure;
            if (enclosureMap.containsKey(e.getApplicationFormEnclosureId())) {
                applicationFormEnclosure = enclosureMap.get(e.getApplicationFormEnclosureId());
            } else {
                applicationFormEnclosure = new ApplicationFormEnclosure();
                applicationFormEnclosure.setFormId(applicationForm.getFormId());
                applicationFormEnclosure.setIsDeleted(SwitchEnum.NO.getId());
            }
            if (StringUtils.isBlank(e.getFileCode())) {
                throw new BusinessException(BaseEnum.ERROR_PARAMETER, "表单附件code不能为空");
            }
            FileRespDTO fileRespDTO = remoteFileService.findBaseByFileCode(e.getFileCode());
            applicationFormEnclosure.setFileId(fileRespDTO.getFileId());

            return applicationFormEnclosure;
        }).collect(Collectors.toList());

        // 删除
        modifies.addAll(formEnclosureList.stream()
                .filter(e -> !enclosuresIds.contains(e.getFormEnclosureId()))
                .peek(e -> e.setIsDeleted(SwitchEnum.YES.getId()))
                .toList());

        logService.saveAndCheck(this.baseMapper, ApplicationFormEnclosure::getFormEnclosureId, modifies);
    }

    /**
     * 删除表单编号规则
     *
     * @param formId formId
     */
    @Override
    public void deleteByFormId(Long formId) {
        List<ApplicationFormEnclosure> enclosures = this.baseMapper.findByFormId(formId);
        enclosures.forEach(e -> e.setIsDeleted(SwitchEnum.YES.getId()));
        logService.saveAndCheck(this.baseMapper, ApplicationFormEnclosure::getFormEnclosureId, enclosures);
    }

    /**
     * 复制表单编号规则
     *
     * @param source 复制源表单
     * @param target 复制目标表单
     */
    @Override
    public void copyFormEnclosure(ApplicationForm source, ApplicationForm target) {
        List<ApplicationFormEnclosure> sourceEnclosures = this.baseMapper.findByFormId(source.getFormId());
        List<ApplicationFormEnclosure> enclosures = StreamUtil.transListT(sourceEnclosures, e -> this.copyFormEnclosure(e, target.getFormId()));
        logService.saveAndCheck(this.baseMapper, ApplicationFormEnclosure::getFormEnclosureId, enclosures);
    }

    /**
     * 删除表单规则
     *
     * @param form form
     */
    @Override
    public void deleteFormEnclosure(ApplicationForm form) {
        List<ApplicationFormEnclosure> enclosures = this.baseMapper.findByFormId(form.getFormId()).stream()
                .peek(e -> e.setIsDeleted(SwitchEnum.YES.getId()))
                .collect(Collectors.toList());

        logService.saveAndCheck(this.baseMapper, ApplicationFormEnclosure::getFormEnclosureId, enclosures);
    }

    private ApplicationFormEnclosure copyFormEnclosure(ApplicationFormEnclosure enclosure, Long targetFormId) {
        ApplicationFormEnclosure copyFormEnclosure = BeanUtil.copyProperties(enclosure, ApplicationFormEnclosure.class);
        copyFormEnclosure.setFormEnclosureId(null);
        copyFormEnclosure.setFormId(targetFormId);

        return copyFormEnclosure;
    }
}
